package com.qf.base.utils;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

//异步线程池
public class AsyncBatchCallUtil {
    private static ExecutorService executorPool;
    static {
        //线程池维护线程的最少数量
        //线程池至少会保持改数量的线程存在，即使没有任何任务执行
        int corePoolSize=5;
        //线程池维护线程的最大数量
        int maxPoolSize=10;
        //线程池维护的线程最大的空闲时间
        long keepaLiveTime=10;
        //空闲时间的单位
        TimeUnit unit=TimeUnit.SECONDS;
        //线程池使用的缓冲队列
        // ArrayBlockingQueue  有界队列，需要指定队列的大小，如果队列满了，会触发线程的RejectedExecutionHandler的
        //LinkedBlockingQueue 无界队列，可以无限向队列中添加任务，直到内存溢出
        //SynchronousQueue  阻塞队列  每一个put任务都必须等待一个task，可以理解为容量只有1的队列
        //PriorityBlockingQueue  优先队列，设置任务的时候，可以
        BlockingQueue<Runnable> workQueue=new ArrayBlockingQueue<>(6);
        //线程工厂
        ThreadFactory threadFactory=new AsyncBatchCallUtil.UserThreadFactory("batch");
        //队列满了的handler
        RejectedExecutionHandler handler=new AsyncBatchCallUtil.MyRejectPolicy();
        /**
         * 实例化线程池
         */
        executorPool=new ThreadPoolExecutor(corePoolSize,maxPoolSize,keepaLiveTime,unit,workQueue,threadFactory,handler);

    }
    public static void execute(Runnable task){
        executorPool.execute(task);
    }
    /**
     * 创建线程工厂
     */
    static class UserThreadFactory implements ThreadFactory{
        private final String namePrefix;
        private final AtomicInteger nextId=new AtomicInteger(1);
        UserThreadFactory(String groupName){
            namePrefix="From UserThreadFactory's"+groupName+"-Worker-";

        }
        @Override
        public Thread newThread(Runnable task) {
            String name=namePrefix+nextId.getAndIncrement();
            Thread thread=new Thread(null,task,name);
            return thread;
        }
    }
    /**
     * 我们使用有界队列，当队列满了，会触发RejectedExecutionHandler
     * 因此自定义RejectedExecutionHandler
     */
    static class MyRejectPolicy implements RejectedExecutionHandler{

        @Override
        public void rejectedExecution(Runnable task, ThreadPoolExecutor executor) {
            System.out.println(task);
        }
    }





}
